package org.belkodevelop.token.service;

import java.util.Calendar;
import org.apache.commons.codec.digest.DigestUtils;
import org.belkodevelop.token.dao.TokenDAO;
import org.belkodevelop.token.domain.Token;
import org.belkodevelop.token.exception.TokenNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
public class TokenService {

    @Value("${web.token.salt}")
    private String tokenSalt;
    
    @Autowired
    private TokenDAO tokenDAO;
    
    private String getHash(String data) {
        return DigestUtils.md5Hex(data + tokenSalt);
    }
    
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public Token createToken(String data) {
        Token token = new Token();
        String hash = getHash(data);
        token.setValue(hash);
        if (tokenDAO.getToken(hash) != null) {
            tokenDAO.removeToken(hash);
        }
        tokenDAO.createToken(token);
        return token;
    }
    
    @Transactional(readOnly=true)
    public Token getToken(String value) throws TokenNotFoundException {
        Token token = tokenDAO.getToken(value);
        if (token == null) {
            throw new TokenNotFoundException();
        }
        return tokenDAO.getToken(value);
    }
    
    @Transactional
    public void removeToken(String value) {
        tokenDAO.removeToken(value);
    }

    @Transactional(propagation= Propagation.REQUIRES_NEW)
    public boolean checkToken(String value, String data, int seconds) throws TokenNotFoundException {
        Token token = getToken(value);

        Calendar now = Calendar.getInstance();
        now.add(Calendar.SECOND, seconds);
        if (token.getValue().equals(getHash(data)) && token.getDateCreate().before(now.getTime())) {
            return true;
        }
        tokenDAO.removeToken(value);
        return false;
    }
    
}
